gusucode.com > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序 > VC++ 基于IE内核功能很齐全的浏览器(支持多标签)-源码程序/code/Explorer/DirTreeCtrl.cpp
//Download by http://www.NewXing.com // DirTreeCtrl.cpp: // // wrapped CTreeCtrl to select and or display folders and files (optional ) // #include "stdafx.h" #include "DirTreeCtrl.h" #include "SortStringArray.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CDirTreeCtrl CDirTreeCtrl::CDirTreeCtrl() { m_strRoot = ""; // Auf Leer setzen } CDirTreeCtrl::~CDirTreeCtrl() { m_imgList.Detach(); } BEGIN_MESSAGE_MAP(CDirTreeCtrl, CTreeCtrl) //{{AFX_MSG_MAP(CDirTreeCtrl) ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // Behandlungsroutinen f黵 Nachrichten CDirTreeCtrl BOOL CDirTreeCtrl::DisplayTree(LPCTSTR strRoot, BOOL bFiles) { DWORD dwStyle = GetStyle(); // read the windowstyle if ( dwStyle & TVS_EDITLABELS ) { // Don't allow the user to edit ItemLabels ModifyStyle( TVS_EDITLABELS , 0 ); } // Display the DirTree with the Rootname e.g. C:\ // if Rootname == NULL then Display all Drives on this PC // First, we need the system-ImageList DeleteAllItems(); if ( !GetSysImgList() ) return FALSE; m_bFiles = bFiles; // if TRUE, Display Path- and Filenames if ( strRoot == NULL || strRoot[0] == '\0' ) { if ( !DisplayDrives() ) return FALSE; m_strRoot = ""; } else { m_strRoot = strRoot; if ( m_strRoot.Right(1) != '\\' ) m_strRoot += "\\"; //HTREEITEM hParent = AddItem( TVI_ROOT, m_strRoot ); DisplayPath( TVI_ROOT, strRoot ); //Expand(hParent,TVE_EXPAND); } return TRUE; } ///////////////////////////////////////////////// BOOL CDirTreeCtrl::GetSysImgList() ///////////////////////////////////////////////// { SHFILEINFO shFinfo; HIMAGELIST hImgList = NULL; if ( GetImageList( TVSIL_NORMAL ) ) m_imgList.Detach(); hImgList = (HIMAGELIST)SHGetFileInfo( "C:\\", 0, &shFinfo, sizeof( shFinfo ), SHGFI_SYSICONINDEX | SHGFI_SMALLICON ); if ( !hImgList ) { m_strError = "Cannot retrieve the Handle of SystemImageList!"; return FALSE; } if ( !m_imgList.Attach( hImgList ) ) { m_strError = "Cannot Attach SystemImageList-Handle"; return FALSE; } SetImageList( &m_imgList, TVSIL_NORMAL ); return TRUE; // OK } BOOL CDirTreeCtrl::DisplayDrives() { // // Displaying the Availible Drives on this PC // This are the First Items in the TreeCtrl // DeleteAllItems(); char szDrives[128]; char* pDrive; if ( !GetLogicalDriveStrings( sizeof(szDrives), szDrives ) ) { m_strError = "Error Getting Logical DriveStrings!"; return FALSE; } pDrive = szDrives; while( *pDrive ) { HTREEITEM hParent = AddItem( TVI_ROOT, pDrive ); if ( FindSubDir( pDrive ) ) InsertItem( "", 0, 0, hParent ); pDrive += strlen( pDrive ) + 1; } return TRUE; } void CDirTreeCtrl::DisplayPath(HTREEITEM hParent, LPCTSTR strPath) { // // Displaying the Path in the TreeCtrl // CFileFind find; CString strPathFiles = strPath; BOOL bFind; CSortStringArray strDirArray; CSortStringArray strFileArray; if ( strPathFiles.Right(1) != "\\" ) strPathFiles += "\\"; strPathFiles += "*.*"; bFind = find.FindFile( strPathFiles ); while ( bFind ) { bFind = find.FindNextFile(); if ( find.IsDirectory() && !find.IsDots() ) { strDirArray.Add( find.GetFilePath() ); } if ( !find.IsDirectory() && m_bFiles ) { CString strFileName=find.GetFilePath(); if(strFileName.Right(4).CompareNoCase(".URL")==0) strFileArray.Add(strFileName); } } strDirArray.Sort(); SetRedraw( FALSE ); CWaitCursor wait; for ( int i = 0; i < strDirArray.GetSize(); i++ ) { HTREEITEM hItem = AddItem( hParent, strDirArray.GetAt(i) ); if ( FindSubDir( strDirArray.GetAt(i) ) ) InsertItem( "", 0, 0, hItem ); } if ( m_bFiles ) { strFileArray.Sort(); for ( i = 0; i < strFileArray.GetSize(); i++ ) { HTREEITEM hItem = AddItem( hParent, strFileArray.GetAt(i),FALSE); } } SetRedraw( TRUE ); } HTREEITEM CDirTreeCtrl::AddItem(HTREEITEM hParent, LPCTSTR strPath,BOOL bFolder) { // Adding the Item to the TreeCtrl with the current Icons SHFILEINFO shFinfo; int iIcon, iIconSel; CString strTemp = strPath; if ( strTemp.Right(1) != '\\' ) strTemp += "\\"; if ( !SHGetFileInfo( strTemp, 0, &shFinfo, sizeof( shFinfo ), SHGFI_ICON | SHGFI_SMALLICON ) ) { m_strError = "Error Gettting SystemFileInfo!"; return NULL; } iIcon = shFinfo.iIcon; if ( !SHGetFileInfo( strTemp, 0, &shFinfo, sizeof( shFinfo ), SHGFI_ICON | SHGFI_OPENICON | SHGFI_SMALLICON ) ) { m_strError = "Error Gettting SystemFileInfo!"; return NULL; } iIconSel = shFinfo.iIcon; if ( strTemp.Right(1) == "\\" ) strTemp.SetAt( strTemp.GetLength() - 1, '\0' ); HTREEITEM hNewItem; //hNewItem hItem=InsertItem( strTemp, iIcon, iIconSel, hParent); CString strSubName=GetSubPath(strTemp); if(!bFolder) { strSubName=strSubName.Left(strSubName.GetLength()-4); } hNewItem=InsertItem(strSubName, iIcon, iIconSel, hParent ); if(bFolder) { SetItemData(hNewItem,1);//目录的话 } else { SetItemData(hNewItem,0);//目录的话 } return hNewItem; } LPCTSTR CDirTreeCtrl::GetSubPath(LPCTSTR strPath) { // // getting the last SubPath from a PathString // e.g. C:\temp\readme.txt // the result = readme.txt static CString strTemp; int iPos; strTemp = strPath; if ( strTemp.Right(1) == '\\' ) strTemp.SetAt( strTemp.GetLength() - 1, '\0' ); iPos = strTemp.ReverseFind( '\\' ); if ( iPos != -1 ) strTemp = strTemp.Mid( iPos + 1); return (LPCTSTR)strTemp; } BOOL CDirTreeCtrl::FindSubDir( LPCTSTR strPath) { // // Are there subDirs ? // CFileFind find; CString strTemp = strPath; BOOL bFind; if (_tcslen(strPath) == 3 ) { if (strPath[1] == ':' && strPath[2] =='\\') strTemp += "*.*"; else strTemp += "\\*.*"; } else strTemp += "\\*.*"; bFind = find.FindFile( strTemp ); while ( bFind ) { bFind = find.FindNextFile(); if ( find.IsDirectory() && !find.IsDots() ) { return TRUE; } if ( !find.IsDirectory() && m_bFiles && !find.IsHidden() ) return TRUE; } return FALSE; } void CDirTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; CString strPath; if ( pNMTreeView->itemNew.state & TVIS_EXPANDED ) { //UINT uTest = TVIS_EXPANDEDONCE; ExpandItem( pNMTreeView->itemNew.hItem, TVE_EXPAND ); /* // // Delete All items // And display the subpath // HTREEITEM hChild = GetChildItem( pNMTreeView->itemNew.hItem ); while ( hChild ) { DeleteItem( hChild ); hChild = GetChildItem( pNMTreeView->itemNew.hItem ); } strPath = GetFullPath( pNMTreeView->itemNew.hItem ); DisplayPath( pNMTreeView->itemNew.hItem, strPath ); */ } else { // // Delete the Items, but leave one there, for // expanding the item next time // HTREEITEM hChild = GetChildItem( pNMTreeView->itemNew.hItem ); while ( hChild ) { DeleteItem( hChild ); hChild = GetChildItem( pNMTreeView->itemNew.hItem ); } InsertItem( "", pNMTreeView->itemNew.hItem ); } *pResult = 0; } CString CDirTreeCtrl::GetFullPath(HTREEITEM hItem) { // get the Full Path of the item CString strReturn; CString strTemp; HTREEITEM hParent = hItem; strReturn = ""; while ( hParent ) { strTemp = GetItemText( hParent ); strTemp += "\\"; strReturn = strTemp + strReturn; hParent = GetParentItem( hParent ); } strReturn=m_strRoot + strReturn; if ( strReturn.Right(1) == '\\' ) strReturn.SetAt( strReturn.GetLength() - 1, '\0' ); if(GetItemData(hItem)==0)//是文件 { strReturn.SetAt( strReturn.GetLength() - 1, '.' ); strReturn=strReturn+"url"; } return strReturn; } BOOL CDirTreeCtrl::SetSelPath(LPCTSTR strPath) { // Setting the Selection in the Tree HTREEITEM hParent = TVI_ROOT; int iLen = strlen(strPath) + 2; char* pszPath = new char[iLen]; char* pPath = pszPath; BOOL bRet = FALSE; if ( !IsValidPath( strPath ) ) { delete [] pszPath; // this must be added 29.03.99 return FALSE; } strcpy( pszPath, strPath ); strupr( pszPath ); if ( pszPath[strlen(pszPath)-1] != '\\' ) strcat( pszPath, "\\" ); int iLen2 = strlen( pszPath ); for (WORD i = 0; i < iLen2; i++ ) { if ( pszPath[i] == '\\' ) { SetRedraw( FALSE ); pszPath[i] = '\0'; hParent = SearchSiblingItem( hParent, pPath ); if ( !hParent ) // Not found! break; else { // Info: // the notification OnItemExpanded // will not called every time // after the call Expand. // You must call Expand with TVE_COLLAPSE | TVE_COLLAPSERESET // to Reset the TVIS_EXPANDEDONCE Flag UINT uState; uState = GetItemState( hParent, TVIS_EXPANDEDONCE ); if ( uState ) { Expand( hParent, TVE_EXPAND ); Expand( hParent, TVE_COLLAPSE | TVE_COLLAPSERESET ); InsertItem("", hParent ); // insert a blank child-item Expand( hParent, TVE_EXPAND ); // now, expand send a notification } else Expand( hParent, TVE_EXPAND ); } pPath += strlen(pPath) + 1; } } delete [] pszPath; if ( hParent ) // Ok the last subpath was found { SelectItem( hParent ); // select the last expanded item bRet = TRUE; } else { bRet = FALSE; } SetRedraw( TRUE ); return bRet; } HTREEITEM CDirTreeCtrl::SearchSiblingItem( HTREEITEM hItem, LPCTSTR strText) { HTREEITEM hFound = GetChildItem( hItem ); CString strTemp; while ( hFound ) { strTemp = GetItemText( hFound ); strTemp.MakeUpper(); if ( strTemp == strText ) return hFound; hFound = GetNextItem( hFound, TVGN_NEXT ); } return NULL; } void CDirTreeCtrl::ExpandItem(HTREEITEM hItem, UINT nCode) { CString strPath; if ( nCode == TVE_EXPAND ) { HTREEITEM hChild = GetChildItem( hItem ); while ( hChild ) { DeleteItem( hChild ); hChild = GetChildItem( hItem ); } strPath = GetFullPath( hItem ); DisplayPath( hItem, strPath ); } } BOOL CDirTreeCtrl::IsValidPath(LPCTSTR strPath) { // This function check the Pathname HTREEITEM hChild; CString strItem; CString strTempPath = strPath; BOOL bFound = FALSE; CFileFind find; hChild = GetChildItem( TVI_ROOT ); strTempPath.MakeUpper(); while ( hChild ) { strItem = GetItemText( hChild ); strItem.MakeUpper(); if ( strItem == strTempPath.Mid( 0, strItem.GetLength() ) ) { bFound = TRUE; break; } hChild = GetNextItem( hChild, TVGN_NEXT ); } if ( !bFound ) return FALSE; if ( find.FindFile( strPath ) ) return TRUE; return FALSE; }